#include "tool.h"
#include <iostream>
#include <string>
#include <list>
#include <vector>
#include <map>
#include <stack>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

tool::tool()
{
    //求一个数组中某部分的平均数的函数
    double average2(const vector<double>& arr, int first, int length)
    {
        double sum = 0;
        int k = 0;
        if (arr.size() - first < length) {
            for (int i = first; i < arr.size(); i++) {
                sum += arr[i];
                k = k + 1;
                if (k == length) {
                    break;
                }
            }
            return sum / (arr.size() - first);
        }
        else {
            for (int i = first; i < arr.size(); i++) {
                sum += arr[i];
                k = k + 1;
                if (k == length) {
                    break;
                }
            }
            return sum / length;
        }
    }


    //显示一个图片的最大连通域,并用白色标记,需使用二值化的结果导入（原始图像，二值图像，导出图像）
    void Showlargest(Mat srcMat, Mat binaryMat, Mat& resultMat, int X) {
        Mat labelMat;
        Mat statsMat;
        Mat centrMat;
        int nComp = cv::connectedComponentsWithStats(binaryMat, labelMat, statsMat, centrMat, X, CV_32S);
        int maxpix = 0;//最大连通域的像素点数最大连通域的序号
        int max = 0;//最大连通域的序号
        for (int i = 1; i < nComp; i++) {
            if (statsMat.at<int>(i, 4) > maxpix) {
                maxpix = statsMat.at<int>(i, 4);
                max = i;
            }
        }
        resultMat = cv::Mat::zeros(srcMat.size(), CV_8UC3);
        std::vector<cv::Vec3b> colors(nComp);
        colors[0] = cv::Vec3b(0, 0, 0);	//背景使用黑色
        colors[max] = cv::Vec3b(255, 255, 255);	//最大连通域使用白色
        //对所有像素按照连通域编号进行着色（只有黑白）
        for (int y = 0; y < srcMat.rows; y++) {
            for (int x = 0; x < srcMat.cols; x++) {
                int label = labelMat.at<int>(y, x);
                CV_Assert(0 <= label && label <= nComp);
                resultMat.at<cv::Vec3b>(y, x) = colors[label];
            }
        }
    }
    //显示最大连通域的右侧区域，逐行从右向左扫描
    void Showright(Mat& resultMat, int X1, int X2) {
        int i, j;
        int cPointR, cPointG, cPointB;
        int a = 0;
        //int X = 200;//设置宽度像素
        for (i = 0; i < resultMat.rows; i++) {
            for (j = resultMat.cols - 1; j >= 0; j--) {
                cPointB = resultMat.at<Vec3b>(i, j)[0];
                cPointG = resultMat.at<Vec3b>(i, j)[1];
                cPointR = resultMat.at<Vec3b>(i, j)[2];
                if (cPointB == 255 && cPointG == 255 && cPointR == 255) {
                    a = j;
                    break;
                }
            }
            if (a > 0) {
                for (j = 0; j < resultMat.cols; j++) {
                    if (j > a + X1 && j <= a + X2) {
                        resultMat.at<Vec3b>(i, j)[0] = 255;
                        resultMat.at<Vec3b>(i, j)[1] = 255;
                        resultMat.at<Vec3b>(i, j)[2] = 255;
                    }
                    else {
                        resultMat.at<Vec3b>(i, j)[0] = 0;
                        resultMat.at<Vec3b>(i, j)[1] = 0;
                        resultMat.at<Vec3b>(i, j)[2] = 0;
                    }
                }
                a = 0;
            }
        }
    }


    void Showleft(Mat& resultMat, int X1, int X2) {
        int i, j;
        int cPointR, cPointG, cPointB;
        int a = 0;
        //int X = 200;//设置宽度像素
        for (i = 0; i < resultMat.rows; i++) {
            for (j = resultMat.cols - 1; j >= 0; j--) {
                cPointB = resultMat.at<Vec3b>(i, j)[0];
                cPointG = resultMat.at<Vec3b>(i, j)[1];
                cPointR = resultMat.at<Vec3b>(i, j)[2];
                if (cPointB == 255 && cPointG == 255 && cPointR == 255) {
                    a = j;
                    break;
                }
            }

                for (j = 0; j < resultMat.cols; j++) {
                    if (j > a - X2 && j <= a - X1) {
                        resultMat.at<Vec3b>(i, j)[0] = 255;
                        resultMat.at<Vec3b>(i, j)[1] = 255;
                        resultMat.at<Vec3b>(i, j)[2] = 255;
                    }
                    else {
                        resultMat.at<Vec3b>(i, j)[0] = 0;
                        resultMat.at<Vec3b>(i, j)[1] = 0;
                        resultMat.at<Vec3b>(i, j)[2] = 0;
                    }
                }


        }
    }

    //将提取出的图像边缘对齐，按照一定范围内的值取平均数
    void Duiqi(Mat& resultMat, int X2, int W) {
        int i, j, k;
        k = 0;
        int a = 0;
        int cPointR, cPointG, cPointB;
        for (i = 0; i < resultMat.rows; i++) {
            for (j = resultMat.cols - 1; j >= 0; j--) {
                cPointB = resultMat.at<Vec3b>(i, j)[0];
                cPointG = resultMat.at<Vec3b>(i, j)[1];
                cPointR = resultMat.at<Vec3b>(i, j)[2];
                if (cPointB == 255 && cPointG == 255 && cPointR == 255) {
                    k = k + 1;
                    break;
                }
            }
        }
        vector<double> arr(k);
        k = 0;
        for (i = 0; i < resultMat.rows; i++) {
            for (j = 0; j < resultMat.cols; j++) {
                cPointB = resultMat.at<Vec3b>(i, j)[0];
                cPointG = resultMat.at<Vec3b>(i, j)[1];
                cPointR = resultMat.at<Vec3b>(i, j)[2];
                if (cPointB == 255 && cPointG == 255 && cPointR == 255) {
                    arr[k] = j;
                    k = k + 1;
                    break;
                }
            }
        }
        int s = -1;
        for (i = 0; i < resultMat.rows; i++) {
            for (j = resultMat.cols - 1; j >= 0; j--) {
                cPointB = resultMat.at<Vec3b>(i, j)[0];
                cPointG = resultMat.at<Vec3b>(i, j)[1];
                cPointR = resultMat.at<Vec3b>(i, j)[2];
                if (cPointB == 255 && cPointG == 255 && cPointR == 255) {
                    a = j;
                    s = s + 1;
                    break;
                }
            }
            if (a > 0) {
                int Y = average2(arr, s, W);
                for (j = 0; j < resultMat.cols; j++) {
                    if (j > Y && j <= Y + X2) {
                        resultMat.at<Vec3b>(i, j)[0] = 255;
                        resultMat.at<Vec3b>(i, j)[1] = 255;
                        resultMat.at<Vec3b>(i, j)[2] = 255;
                    }
                    else {
                        resultMat.at<Vec3b>(i, j)[0] = 0;
                        resultMat.at<Vec3b>(i, j)[1] = 0;
                        resultMat.at<Vec3b>(i, j)[2] = 0;
                    }
                }
                a = 0;
            }
        }
    }

}

